import 'dart:async';
import 'dart:io';

enum DeviceConnectionState {
  disconnected,
  connecting,
  connected,
}

class TcpConnectionService {
  final String host;
  final int port;
  Socket? _socket;
  DeviceConnectionState _connectionState = DeviceConnectionState.disconnected;
  StreamController<DeviceConnectionState> _connectionStateController = StreamController.broadcast();
  final StreamController<String> _messageController = StreamController.broadcast();

  StreamController<String> _errorController = StreamController.broadcast();

  TcpConnectionService({required this.host, required this.port});

  // 流供外部监听
  DeviceConnectionState get connectionState => _connectionState;
  Stream<DeviceConnectionState> get connectionStateStream => _connectionStateController.stream;
  Stream<String> get messageStream => _messageController.stream;

  Stream<String> get errorStream => _errorController.stream;

  Future<void> connect() async {
    if (_connectionState == DeviceConnectionState.connecting ||
        _connectionState == DeviceConnectionState.connected) {
      return;
    }

    _updateConnectionState(DeviceConnectionState.connecting);

    try {
      // 设置连接超时
      final timeout = Duration(seconds: 10);

      // 建立TCP连接
      _socket = await Socket.connect(
        host,
        port,
        timeout: timeout,
      ).timeout(
        timeout,
        onTimeout: () {
          throw TimeoutException('连接超时');
        },
      );

      // 配置TCP选项
      await _configureTcpOptions();

      // 连接成功
      _updateConnectionState(DeviceConnectionState.connected);
      print('Connection is ready');

      // 监听连接关闭
      _socket?.done.then((_) {
        _updateConnectionState(DeviceConnectionState.disconnected);
        print('Connection closed normally');
      });

      // 监听错误
      _socket?.handleError((error) {
        _handleError(error);
      });

      // 监听接收数据
      _socket?.listen((data) {
          final message = String.fromCharCodes(data).trim();
          // print('接收到客户端消息 data: $data');
          // print('接收到客户端消息 message: $message');
          _messageController.add(message);
      },
        onError: (error) {
          _errorController.add('接收数据错误: $error');
          disconnect();
        },
        onDone: () {
          _errorController.add('连接已关闭');
          disconnect();
        },
        cancelOnError: true,
      );

    } catch (e) {
      _handleError(e.toString());
      _updateConnectionState(DeviceConnectionState.disconnected);
    }
  }

  Future<void> _configureTcpOptions() async {
    if (_socket == null) return;

    try {
      // 禁用Nagle算法 (TCP_NODELAY)
      await _socket?.setOption(SocketOption.tcpNoDelay, true);

      // 启用TCP保活
      // await _socket?.setOption(SocketOption.keepAlive, true);

      // 设置保活参数（根据平台支持情况）
      if (Platform.isLinux || Platform.isAndroid) {
        // await _socket?.setOption(SocketOption.tcpKeepAliveIdle, 300); // 5分钟无活动后发送保活包
        // await _socket?.setOption(SocketOption.tcpKeepAliveInterval, 60); // 保活包间隔
        // await _socket?.setOption(SocketOption.tcpKeepAliveCount, 5); // 重试次数
      }

      print('TCP options configured successfully');
    } catch (e) {
      print('Error configuring TCP options: $e');
      _errorController.add('配置TCP选项失败: $e');
    }
  }

  void disconnect() {
    if (_socket != null) {
      _socket?.destroy();
      _socket = null;
      _updateConnectionState(DeviceConnectionState.disconnected);
      print('Connection cancelled');
    }
  }

  void sendData(List<int> data) {
    if (_socket != null && _connectionState == DeviceConnectionState.connected) {
      _socket?.add(data);
    } else {
      _errorController.add('无法发送数据，连接未建立');
    }
  }

  Stream<List<int>> get dataStream {
    return _socket?.asBroadcastStream() ?? Stream.empty();
  }

  void _updateConnectionState(DeviceConnectionState newState) {
    _connectionState = newState;
    _connectionStateController.add(newState);
  }

  void _handleError(String errorMessage) {
    print('Connection error: $errorMessage');
    _errorController.add(errorMessage);
  }

  void dispose() {
    disconnect();
    _connectionStateController.close();
    _errorController.close();
  }
}
